﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data.Common;
using System.Data;
using System.Configuration;
using XMK.Utils;

namespace XMK.Framework.DataAccess
{
    /// <summary>
    /// 数据提供工厂
    /// </summary>
    public abstract class DbProvider
    {
        #region 属性
        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        public string ConnString{get;set;}
        /// <summary>
        /// 数据库操作超时时间
        /// </summary>
        protected int commandTimeout = 600;
        /// <summary>
        /// 数据库操作超时时间[默认600]
        /// </summary>
        public virtual int CommandTimeout
        {
            get { return commandTimeout; }
            set { commandTimeout = value; }
        }
        #endregion

        #region 子类需实现方法
        /// <summary>
        /// 实例化数据库操作命令
        /// </summary>
        /// <returns>数据库操作命令</returns>
        public abstract IDbCommand CreateCommand();
        /// <summary>
        /// 实例化数据库连接
        /// </summary>
        /// <returns>数据库连接</returns>
        public abstract IDbConnection CreateConnection();
        /// <summary>
        /// 实例化数据库适配器
        /// </summary>
        /// <returns>数据库适配器</returns>
        public abstract IDbDataAdapter CreateDataAdapter();
        /// <summary>
        /// 实例化数据库参数
        /// </summary>
        /// <returns>数据库操作的参数</returns>
        public abstract IDbDataParameter CreateParameter();
        /// <summary>
        /// 取得参数的前缀
        /// </summary>
        public abstract string ParamPrefix { get; }

        /// <summary>
        /// 开始数据库缓存依赖
        /// </summary>
        public abstract void DbDependencyStart();
        /// <summary>
        /// 结束数据库缓存依赖
        /// </summary>
        public abstract void DbDependencyStop();
        /// <summary>
        /// 创建数据库依赖
        /// </summary>
        /// <typeparam name="T">数据库依赖保存的列表类型</typeparam>
        /// <param name="sqlText">数据库依赖查询字符串</param>
        /// <param name="fun">反序列化类型委托</param>
        /// <returns>数据库依赖实现类</returns>
        public abstract DbDependency<T> CreateDbDependency<T>(string sqlText, DataRowFullInfoFun<T> fun) where T : new();
        /// <summary>
        /// 对命令进行参数处理
        /// </summary>
        /// <param name="cmd">存储过程命令</param>
        /// <param name="dbCmdInfo">命令语句对象</param>
        internal abstract void DeriveParameters(IDbCommand cmd, DbCmdInfo dbCmdInfo);
        #endregion

        #region 工程内部使用方法
        internal IDbDataParameter CreateParameter(string paramName, object paramValue)
        {
            IDbDataParameter param = this.CreateParameter(paramName);
            param.Value = paramValue;
            return param;
        }
        internal IDbDataParameter CreateParameter(string paramName)
        {
            IDbDataParameter param = this.CreateParameter();
            param.ParameterName = this.ParamPrefix + paramName;
            return param;
        }
        internal IDbDataParameter CreateParameter(string paramName, ParameterDirection direction, DbType dbType)
        {
            IDbDataParameter param = this.CreateParameter(paramName);
            param.Direction = direction;
            param.DbType = dbType;
            return param;
        }

        internal IDbDataParameter CreateParameter(string paramName, object paramValue, 
            ParameterDirection direction,DbType dbType,int size)
        {
            IDbDataParameter param = this.CreateParameter(paramName, paramValue);
            param.DbType = dbType;
            param.Size = size;
            param.Direction = direction;
            return param;
        }
        #endregion

        //#region 外部调用方法
        ///// <summary>
        ///// 根据配置文件获取数据库实现
        ///// </summary>
        ///// <param name="dbName">Web.Config的connectionStrings配置节的name</param>
        ///// <returns>数据库实现类</returns>
        //public static DbProvider GetDbProvider(string dbName)
        //{
        //    ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings[dbName];
        //    if (settings == null)
        //        return null;
        //    string dbProviderName = settings.ProviderName;
        //    if (String.IsNullOrEmpty(dbProviderName))
        //        return null;
        //    try
        //    {
        //        return (DbProvider)ReflectionHelper.CreateInstance("XMK.Framework", dbProviderName, new Object[] { settings.ConnectionString });
        //    }
        //    catch
        //    {
        //        MessageManager.SendMessage("W8001", "数据库连接字符串配置错误！");
        //        return null;
        //    }
        //}
        //#endregion
    }
}
